﻿using System;
using System.IO;


namespace Zealib.Extensions
{
    /// <summary>
    /// Extensions for <seealso cref="System.IO.BinaryWriter"/> class.
    /// </summary>
    public static class BinaryWriterExtensions
    {        
        //TODO: Fix unwanted write.

        public static void Write(this BinaryWriter self, EndianOrder order, short value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = BitConverter.GetBytes(value);
            Array.Reverse(buffer);
            value = BitConverter.ToInt16(buffer, 0);
            self.Write(value);
        }

        public static void Write(this BinaryWriter self, EndianOrder order, ushort value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = BitConverter.GetBytes(value);
            Array.Reverse(buffer);
            value = BitConverter.ToUInt16(buffer, 0);
            self.Write(value);
        }

        public static void Write(this BinaryWriter self, EndianOrder order, int value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = BitConverter.GetBytes(value);
            Array.Reverse(buffer);
            value = BitConverter.ToInt32(buffer, 0);
            self.Write(value);
        }

        public static void Write(this BinaryWriter self, EndianOrder order, uint value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = BitConverter.GetBytes(value);
            Array.Reverse(buffer);
            value = BitConverter.ToUInt32(buffer, 0);
            self.Write(value);
        }

        public static void Write(this BinaryWriter self, EndianOrder order, long value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = BitConverter.GetBytes(value);
            Array.Reverse(buffer);
            value = BitConverter.ToInt64(buffer, 0);
            self.Write(value);
        }

        public static void Write(this BinaryWriter self, EndianOrder order, ulong value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = BitConverter.GetBytes(value);
            Array.Reverse(buffer);
            value = BitConverter.ToUInt64(buffer, 0);
            self.Write(value);
        }

        public static void Write(this BinaryWriter self, EndianOrder order, float value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = BitConverter.GetBytes(value);
            Array.Reverse(buffer);
            value = BitConverter.ToSingle(buffer, 0);
            self.Write(value);
        }

        public static void Write(this BinaryWriter self, EndianOrder order, double value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = BitConverter.GetBytes(value);
            Array.Reverse(buffer);
            value = BitConverter.ToDouble(buffer, 0);
            self.Write(value);
        }

        public static void Write(this BinaryWriter self, EndianOrder order, decimal value)
        {
            self.IsNotNull();
            if (BitConverter.IsLittleEndian && (order == EndianOrder.LittleEndian))
            {
                self.Write(value);
            }
            byte[] buffer = value.GetBytes();
            Array.Reverse(buffer);
            value = DecimalExtensions.ToDecimal(buffer, 0);
            self.Write(value);
        }
    }
}
